package com.qiqidream.admin.security.filter;

import cn.hutool.core.util.StrUtil;
import com.google.common.collect.Sets;
import com.qiqidream.admin.common.config.IgnoresCustomConfig;
import com.qiqidream.admin.common.constant.StaticConstants;
import com.qiqidream.admin.common.utils.JwtUtil;
import com.qiqidream.admin.common.utils.Multi.MultiReadHttpServletRequest;
import com.qiqidream.admin.common.utils.Multi.MultiReadHttpServletResponse;
import com.qiqidream.admin.monitor.service.LogService;
import com.qiqidream.admin.security.entity.SecurityUser;
import com.qiqidream.admin.security.login.AdminAuthenticationEntryPoint;
import com.qiqidream.admin.system.model.entity.User;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

import static java.lang.String.valueOf;

/**
 * 访问鉴权 - 每次访问接口都会经过此
 * @author QiQiDream
 * @since 2019/11/18 9:56
 */
@Slf4j
@Component
public class MyAuthenticationFilter extends OncePerRequestFilter {

    @Resource
    AdminAuthenticationEntryPoint authenticationEntryPoint;

    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private IgnoresCustomConfig ignoresCustomConfig;

    @Resource
    private LogService logService;

    protected MyAuthenticationFilter() {
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//        System.out.println("请求头类型： " + request.getContentType());
        if ((request.getContentType() == null && request.getContentLength() > 0) ||
                (request.getContentType() != null && !request.getContentType().contains(StaticConstants.REQUEST_HEADERS_CONTENT_TYPE))) {
            filterChain.doFilter(request, response);
            return;
        }

        if (ignoresCustomConfig.checkIgnores(request)) {
            filterChain.doFilter(request, response);
            return;
        }
        MultiReadHttpServletRequest wrappedRequest = new MultiReadHttpServletRequest(request);
        MultiReadHttpServletResponse wrappedResponse = new MultiReadHttpServletResponse(response);

        try {
            String jwt = jwtUtil.getJwtFromRequest(request);
            if (StrUtil.isNotBlank(jwt)) {
                User user = jwtUtil.getUserFromJWT(jwt);

                UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(new SecurityUser(user), null, jwtUtil.getAuthoritiesFromJWT(jwt));
                // 全局注入角色权限信息和登录用户基本信息
                SecurityContextHolder.getContext().setAuthentication(authentication);
            }
            filterChain.doFilter(wrappedRequest, wrappedResponse);
        } catch (ExpiredJwtException e) {
            // jwt令牌过期
            SecurityContextHolder.clearContext();
            this.authenticationEntryPoint.commence(wrappedRequest, response, null);
        } catch (AuthenticationException e) {
            SecurityContextHolder.clearContext();
            this.authenticationEntryPoint.commence(wrappedRequest, response, e);
        }

    }

}
